#!/usr/bin/perl -w


use strict;

use Tk;
use Tk::ROText;
use Tk::Dialog;
use Tk::HList;
use Tk::NoteBook;

use YAML;
use threads;

my %send_mutex;
my %update_mutex;
my %update_string;
my %updater;

sub initialize_menu;
sub initialize_frame;
sub initialize_list;
sub initialize_input;
sub initialize_dialog;
sub initialize_display;


sub parse_input;
sub tab_complete;

my %menu;
my %frame;
my %tab;
my %list;
my %dialog;
my %text;

my $hlist;
my $book;
my $input;

my $window = new MainWindow( -title => 'msqirc' );
my $menu = $window->Menu;




sub parse_input {
  my $string = $input->get;
  $input->delete( 0, length $string );
  if ( $string =~ m|^/| ) {
    print "$string\n";
  }
  &write_to_current_tab( $string );
}

sub write_to_current_tab {
  my $message = shift;
  my $name = $book->raised;
  my $text = $text{ $name };
  
  my ($seconds, $minuets, $hours) = localtime(time);
  $hours   = "0$hours"   if length $hours   == 1;
  $minuets = "0$minuets" if length $minuets == 1;
  $seconds = "0$seconds" if length $seconds == 1;
  
  $message = "$hours:$minuets:$seconds - $message\n" if not $message =~ m/\n$/;
  $text->insert( 'end', $message );  
}

sub tab_complete {
  print "foo\n";
}


###GUI UPDATING

#my %send_mutex;
#my %update_mutex;
#my %update_string;
#my %updater;


#sub send_message_to_gui {
#  my $msg = shift;
#  
#  while ( 1 == $shared_flag) {
#    select(undef, undef, undef, 0.30);
#  }
#  
#  $shared_text = $msg;  
#  $shared_flag = 1;
#}

#sub gui_update {
#  return if not $shared_flag;
#  
#  my $msg = $shared_text;
#  
#  if ($msg) {
#    $txt->insert('end', $msg);
#    $main_window->update();
#  }
#  
#  $shared_flag = 0;
#}
  
sub update_mass {
  for my $target ( keys %update_mutex ) {
    &update( $target );
  }
} 

sub update_tab {
  
  #pull in target or cancel update;
  my $target = shift || return;
  
  #wait for lock to open
  return if( $update_mutex{ $target } );
  
  #lock mutex
  $update_mutex{ $target } = 1;
  
  #run update
  &{ $updater{ tab_write }}( $update_string{ $target } );
  
  #unlock mutexs
  $update_mutex{ $target } = 0;
  $send_mutex{ $target } = 0;
}


$updater{ hlist_add } = sub {
  
  my $message = shift;
  $message =~ m/([^ ]+) ?([^ ]+)?/;
  
  my $host = $1 || warn "No host provided";
  my $chan = $2 || "NO_CHANNEL";
  my $text = $host;
  
  
  if ( $chan ne "NO_CHANNEL" ) {
    $host = "$host-$chan";
    $text = $chan;
  }
  $hlist->add( $host, -text => $text );
};

$updater{ hlist_remove } = sub {
  
  my $target = shift || warn "No target provided\n";
  
  $hlist->delete( 'entry', $target)
};


$updater{ tab_construct } = sub {
  my $name = shift || warn "No name provided\n", return;
  
  $tab{ $name } = $book->add( $name, -label => $name );
  $text{ $name } = $tab{ $name }->Scrolled( "ROText",
                                            -width => 80,
                                            -height => 30,
                                            -wrap => 'word',
                                            -bg => 'white',
                                            -relief => 'sunken',
                                            -scrollbars => 'oe' 
                                          )->pack(-side   => 'top',
                                                  -fill   => 'both',
                                                  -expand => 1);
  
};

$updater{ tab_write } = sub {
  
  my ($taregt, $message) = @_;
  #  my $message = shift;
  #  my $name = $book->raised;
  my $text = $text{ $target };
  
  my ($seconds, $minuets, $hours) = localtime(time);
  $hours   = "0$hours"   if length $hours   == 1;
  $minuets = "0$minuets" if length $minuets == 1;
  $seconds = "0$seconds" if length $seconds == 1;
  
  $message = "$hours:$minuets:$seconds - $message\n" if not $message =~ m/\n$/;
  $text->insert( 'end', $message );  
};

$updater{ tab_destruct } = sub {
  #to be implimented
};


sub initialize_dialog {
  
  
  $dialog{ about } = $window->Dialog( 
                                     -title => 'about', 
                                     -text => "Version 0.01",
                                     -bitmap => 'info',
                                     -buttons => ['Dismiss'],
                                    );
  $dialog{ about }->configure( -wraplength => '6i' );
  
  $dialog{ usage } = $window->Dialog( 
                                     -title => 'Usage',
                                     -text => "Not useable right now." ,
                                     -buttons => ['Dismiss'],
                                    );
}

sub initialize_menu {
  
  $menu{ file } = $menu->cascade( 
                                 -label => '~File',
                                 -tearoff => 0,
                                );
  $menu{ file }->command(
                         -label => 'Quit',
                         -command => sub { exit },
                         -underline => 0,
                        );
                         
  $menu{ edit } = $menu->cascade(
                                 -label => '~Edit',
                                 -tearoff => 0,
                                );
  
  $menu{ help } = $menu-> cascade(
                                  -label => '~Help',
                                  -tearoff => 0,
                                 );
  $menu{ help }->command(
                         -label => 'About',
                         -command => sub { print 'foo\n' },
                         -underline => 0
                        );
}

sub initialize_frame {
  $frame{ super } = $window->Frame()->pack(
                                           -side   => 'top',
                                           -fill   => 'both',
                                           -expand => 1
                                          );
  $frame{ left } =$frame{ super }->Frame()->pack(
                                                 -side   => 'left',
                                                 -fill   => 'y',
                                                 -expand => 1
                                                );
  $frame{ right } = $frame{ super }->pack(
                                          -side   => 'right',
                                          -fill   => 'both'
                                         );
}

sub initialize_list {
  $hlist = $frame{ left }->Scrolled(
                                    'HList',
                                    -width => 20,
                                    -itemtype    => 'text',
                                    -separator   => '-',
                                    -selectmode  => 'single',
                                    -scrollbars  => 'osoe'
                                   )->pack(-side   =>'top',
                                           -fill   => 'y',
                                           -expand => 1,
                                          );
  &{ $updater{ hlist_add } }( 'diagnostic' ); 
}

  
sub initialize_display {
  
  $book = $frame{ right }->NoteBook()->pack;
  &{$updater{  tab_construct }}( 'diagnotic' );
  
  
}
sub initialize_input {
  $input = $frame{ right }->Entry()->pack(-side   => 'left',
                                          -fill   => 'both',
                                          -expand => 1,
                                          -pady   => 2);
  $input->bind("<Return>", \&parse_input );
  $input->bind("<Control-Return>", \&tab_complete );
  $input->bind("<Tab>", \&tab_complete );

}

$window->configure( -menu => $menu );

&initialize_menu;
&initialize_dialog;
&initialize_frame;
&initialize_list;
&initialize_display;
&initialize_input;

$input->focus;
$window->repeat(300, \&update_mass) ;

MainLoop;
